package _6_bridge

import "container/list"

//CheckResult 数据检查结果
type CheckResult struct {
	success  bool
	errorMsg string
}

type CheckCondition struct {
	condition string
}

//DataChecker TURepository  ComparatorFunction 独立发展 UserOneByOneChecker 实现桥接

//DataChecker 数据检查接口
type DataChecker interface {
	check(condition CheckCondition) CheckResult
}

//ComparatorFunction 比较器
type ComparatorFunction interface {
	apply(T interface{}, U interface{}) bool
}

//TURepository 资源接口
type TURepository interface {
	getT(condition CheckCondition) *list.List
	getU(condition CheckCondition) *list.List
}

//User 用户对象
type User struct {
	name string
}

// UserRepository 用户资源
type UserRepository struct {
}

func (o UserRepository) getT(condition CheckCondition) *list.List {
	l := list.New()
	l.PushBack(User{name: "a"})
	l.PushBack(User{name: "b"})
	return l
}

func (o UserRepository) getU(condition CheckCondition) *list.List {
	l := list.New()
	l.PushBack(User{name: "a"})
	l.PushBack(User{name: "b"})
	return l
}

//UserOneByOneChecker 真正的实现
type UserOneByOneChecker struct {
	repository         TURepository
	comparatorFunction ComparatorFunction
}

//NewUserOneByOneChecker UserOneByOneChecker的构造方法
func NewUserOneByOneChecker() *UserOneByOneChecker {
	return &UserOneByOneChecker{
		repository:         UserRepository{},
		comparatorFunction: UserComparatorFunction{},
	}
}

func (o *UserOneByOneChecker) check(condition CheckCondition) CheckResult {
	tList := o.repository.getT(condition)
	uList := o.repository.getU(condition)
	success := o.comparatorFunction.apply(tList, uList)
	if success {
		return CheckResult{success: true}
	}
	return CheckResult{success: true, errorMsg: "检查失败"}
}

type UserComparatorFunction struct {
}

func (u UserComparatorFunction) apply(T interface{}, U interface{}) bool {
	l := T.(*list.List)
	g := U.(*list.List)
	tmp1 := l.Front()
	tmp2 := g.Front()

	for {
		if tmp1.Value == tmp2.Value {
			tmp1 = tmp1.Next()
			tmp2 = tmp2.Next()
			if tmp1 != nil && tmp2 != nil {
				continue
			} else {
				break
			}
		} else {
			return false
		}
	}
	return true
}
